package com.du.spring5.proxy;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * @author : DuJiabao
 * @Date : 2021/2/4 10:17
 * @Project : spring
 * @File : null.java
 * @Desc : 增强的类
 * 用于增强通知的各个方法。分别在代理方法的前、后、环绕等位置执行。
 * 顺序： 环绕前的增强 -> before -> 当前被代理的方法 -> 环绕后的增强 -> after -> afterReturning
 * 有异常的执行顺序 : 环绕前的增强 -> before -> 当前被代理的方法 -> after -> afterThrowing
 */

@Component //通过注解配置
@Aspect // 生成代理对象
@Order(10)
public class UserProxy {
    // 切入点抽取出来
    @Pointcut(value = "execution(* com.du.spring5.bean.User.add(..))")
    public void pointCutConfig() {
    }

    //    设置该方法作为指定方法的前置增强通知
//    * 表示权限修饰符，任意权限均可 后续为指定方法路径 ..为任意参数
    @Before(value = "pointCutConfig()")
    public void before() {
        System.out.println("before");
    }

    //    设置该方法作为指定方法后的增强通知（最终通知）不管是否报错异常、都会执行
    @After(value = "pointCutConfig()")
    public void after() {
        System.out.println("after");
    }

    //     设置该方法为返回后的增强通知（返回通知）
    @AfterReturning(value = "pointCutConfig()")
    public void afterReturning() {
        System.out.println("afterReturning");
    }

    //      设置该方法为，异常的时候开启的通知
    @AfterThrowing(value = "pointCutConfig()")
    public void afterThrowing() {
        System.out.println("afterThrowing");
    }

    //    环绕通知，方法运行之前之后都会执行
    @Around(value = "pointCutConfig()")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("around before");
        proceedingJoinPoint.proceed();
        System.out.println("around after");
    }
}
